package cc.eddic.pratice.programmingparadigms.streampractice.impl;

import cc.eddic.pratice.programmingparadigms.exam.Model.AnswerModel;
import cc.eddic.pratice.programmingparadigms.exam.domain.*;
import cc.eddic.pratice.programmingparadigms.exam.impl.ExamServiceWqjImpl;
import cc.eddic.pratice.programmingparadigms.exam.impl.MasterDataServiceWqjImpl;
import cc.eddic.pratice.programmingparadigms.exam.impl.QuestionBankServiceWqjImpl;
import cc.eddic.pratice.programmingparadigms.streampractice.QuestionAndAnswer;
import cc.eddic.pratice.programmingparadigms.streampractice.StreamPractice;
import lombok.Getter;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;

public class StreamPracticeWqjImpl implements StreamPractice {

    @Override
    public List<QuestionAndAnswer> mapToQuestionAndAnswer(List<Question> questionList) {
        List<QuestionAndAnswer> questionAndAnswerList = questionList.stream()
                .map(question -> new QuestionAndAnswer(
                        question.getNo(),
                        question.getDescription(),
                        question.getOptions().stream().filter(Option::isCorrectAnswer)
                                .findFirst()
                                .orElse(new Option("defaultValue", ' ', false))
                                .getChoice(),
                        question.getOptions().stream().filter(Option::isCorrectAnswer)
                                .findFirst()
                                .orElse(new Option("defaultValue", ' ', false))
                                .getAnswer())
                ).collect(Collectors.toList());

        return questionAndAnswerList;
    }

    //stream对集合进行操作
    //::方法引用
    //QuestionAndAnswer(int no, String question, char choice, String correctAnswer)
    //Question(int no, String description, QuestionType questionType)
    public List<QuestionAndAnswer> normalToQuestionAndAnswer(List<Question> questionList) {
        List<QuestionAndAnswer> questionAndAnswerList = new ArrayList<>();
        for (Question q : questionList) {
            String no = String.valueOf(q.getNo());
            String question = q.getDescription();
            for (Option option : q.getOptions()) {
                if (option.isCorrectAnswer()) {
                    char choice = option.getChoice();
                    String correctAnswer = option.getAnswer();
                    QuestionAndAnswer questionAndAnswer = new QuestionAndAnswer(Integer.getInteger(no), question, choice, correctAnswer);
                    questionAndAnswerList.add(questionAndAnswer);
                }
            }
        }
        return questionAndAnswerList;
    }


    //统计每个人的分数,answerList,先判断每个人对了几道题,再乘以4即可得到每个人的总分
    //新建一个类，存需要的对象
    //普通的计算方法

    public void studentScore() {
        ExamServiceWqjImpl examService = new ExamServiceWqjImpl();
        List<Answer> answerList = examService.importAnswers("");
        QuestionBankServiceWqjImpl questionBankService = new QuestionBankServiceWqjImpl();
        List<AnswerModel> answerModelList = questionBankService.readCorrectAnswers("");
        MasterDataServiceWqjImpl masterDataService = new MasterDataServiceWqjImpl();
        List<Student> studentList = masterDataService.getStudents();

        for (Student student : studentList) {
            int correctNum = 0;
            int studentNum = 0;
            for (Answer answer : answerList){
                if (Objects.equals(answer.getStudent().getName(), student.getName())) {
                    studentNum ++;
                    if (answer.getChoice() == answerModelList.get(answer.getQuestion().getNo()-1).getChoice()){
                        correctNum ++;
                    }
                }
                if (studentNum == answerModelList.size()) {break;}
            }
            correctNum = correctNum * 4;
            //System.out.println(student.getName() + "的分数是 " + correctNum);
        }
    }

    //使用Map方法处理
    //调用之前用Map存储的correctAnswer

@Test
    public void mapStudentScore() {
        ExamServiceWqjImpl examService = new ExamServiceWqjImpl();
        List<Answer> answerList = examService.importAnswers("");
        Map<String, Integer> studentScoreMap = new HashMap<>();

        for (Answer answer : answerList) {
            String studentName = answer.getStudent().getName();
            boolean isCorrect = answer.getQuestion().getOptions().stream()
                    .anyMatch(option -> option.isCorrectAnswer() &&  option.getChoice() == answer.getChoice());
            studentScoreMap.merge(studentName, isCorrect ? 4 : 0, Integer::sum);

        }
        System.out.println(studentScoreMap.get("王巧家"));

    }
    //使用stream方法处理
    public void streamStudentScore() {
        ExamServiceWqjImpl examService = new ExamServiceWqjImpl();
        List<Answer> answerList = examService.importAnswers("");
        final List<studentScore> scoreList = answerList.stream().map(
                        answer -> new Model(
                                answer.getStudent().getName(),
                                answer.getChoice(),
                                answer.getQuestion().getOptions().stream().filter(Option::isCorrectAnswer).
                                        findFirst().orElse(new Option("", '*', true)).getChoice(),
                                answer.getQuestion().getNo())
                )
                .filter(model -> model.choice == model.correctAnswer)
                .collect(Collectors.groupingBy(Model::getStudentName, Collectors.counting()))
                .entrySet().stream()
                .map(entry -> new studentScore(entry.getKey(), entry.getValue().intValue() * 4))
                .sorted(Comparator.comparing(studentScore::getScore).reversed())
                .collect(Collectors.toList());

        scoreList.forEach(studentScore -> System.out.println(studentScore.studentName + " " + studentScore.score));



    }

    @Getter
    static class  studentScore {
        String studentName;
        int score;
        public studentScore(String studentName, int score) {
            this.studentName = studentName;
            this.score = score;
        }

    }

    @Getter
    static class Model {
        String studentName;
        char choice;
        char correctAnswer;
        int questionNo;

        public Model(String studentName, char choice, char correctAnswer, int questionNo) {
            this.studentName = studentName;
            this.choice = choice;
            this.correctAnswer = correctAnswer;
            this.questionNo = questionNo;
        }
    }

}
